package ar.uba.fi.tonyvaliente.commands;

import java.util.ArrayList;
import java.util.LinkedList;

import ar.uba.fi.tonyvaliente.documents.QueryDocumentsResult;
import ar.uba.fi.tonyvaliente.signature.HashFunction;
import ar.uba.fi.tonyvaliente.signature.SignatureConfiguration;
import ar.uba.fi.tonyvaliente.signature.SignatureConfigurationException;
import ar.uba.fi.tonyvaliente.signature.process.SignatureGenerator;
import ar.uba.fi.tonyvaliente.utils.RecursosAplicacion;

public class QuerySignatureCommand extends Command {

	private boolean recognized;
	private String query;
	private boolean showDetails;
	private LinkedList<Integer> documents;
	private String configurationPath;
	private ArrayList<HashFunction> hashFunctions;
	private int length;

	public QuerySignatureCommand(String[] args) {
		super(args);

		recognized = false;
		query = null;
		showDetails = false;
		documents = new LinkedList<Integer>();

		if (args.length > 0) {
			String command = args[0];
			command = command.toLowerCase();
			if (command.equals("-querysignature")) {
				recognized = true;
				if (args.length > 1) {
					configurationPath = RecursosAplicacion.instance().getProperty("hash.config");
					query = args[1];
				}
				if (args.length > 2) {
					showDetails = args[2].equals("showDetails");
				}
			}
		}
	}

	private CommandResult queryDocuments() {
		SignatureConfiguration config = null;
		try {
			config = SignatureConfiguration.loadFromFile(configurationPath);
		} catch (SignatureConfigurationException e) {
			e.printStackTrace();
			return new CommandResult(true, false, e.getMessage());
		}
		hashFunctions = new ArrayList<HashFunction>(config.getHashFunctions());
		length = config.getSignatureLength();
		QueryDocumentsResult results = SignatureGenerator.queryDocuments(query, showDetails, hashFunctions, length);
		
		if (results.getResults().size() == 0)
			return new CommandResult(true, true, "0 documents found");
		else {
			StringBuffer documentList = new StringBuffer();
			documentList.append(results.getMessages());
			documents = results.getResults();
			documentList.append("\n ");
			documentList.append(documents.size());
			documentList.append(" documents found");
			return new CommandResult(true, true, documentList.toString());
		}
	}

	public LinkedList<Integer> getDocumentIds()
	{
		return documents;
	}
	
	public CommandResult execute() {
		if (!recognized)
			return CommandResult.NOT_RECOGNIZED;

		if (query == null)
			return new CommandResult(true, false, "Missing query expression");

		if (!isValidQuery(query))
			return new CommandResult(true, false, "Invalid query expression");

		return queryDocuments();
	}

	public String getSignature() {
		return "-querysignature \"configurationPath\" \"boolean query\" [showDetails]";
	}

	public String getDescription() {
		return "Query the index and return a document's list that matches the query";
	}

	public String[] getExamples() {
		return new String[] {
				String.format("-query \"%s\" \"%s\"", "/var/local/confi/config.properties", "home OR car"),
				String.format("-query \"%s\" \"%s\" showDetails", "/var/local/confi/config.properties", "home OR car") 
				};
	}

	private static boolean isValidQuery(String query) {
		// TODO: implementar
		return true;
	}
}
